import java.text.*;
import java.util.*;

import javax.swing.JOptionPane;

public class Item extends Observable
{

	public static final Map<String, Integer> ITEM_BORROW_DURATIONS = new HashMap<String, Integer>();
	static
	{
		ITEM_BORROW_DURATIONS.put("F", 14);
		ITEM_BORROW_DURATIONS.put("NF", 14);
		ITEM_BORROW_DURATIONS.put("V", 7);
	};

	public static final Map<String, Double> ITEM_FINE_PER_DAY = new HashMap<String, Double>();
	static
	{
		ITEM_FINE_PER_DAY.put("F", 0.15);
		ITEM_FINE_PER_DAY.put("NF", 0.30);
		ITEM_FINE_PER_DAY.put("V", 0.50);
	};

	public Item() 
	{
	}
	public Item(String itemFromFile) throws ParseException 
	{
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm"); 
		String [] tokens = itemFromFile.split(";",0);

		this.itemId = tokens[0];
		this.title = tokens[1];
		this.location = tokens[2];
		this.status = tokens[3];
		this.price = Double.parseDouble(tokens[4]);
		if(tokens[5].isEmpty() || tokens[5] == null)
			this.dueDate = null;
		else
			this.dueDate = df.parse(tokens[5]);
		if(tokens[6].isEmpty() || tokens[6] == null)
			this.borrowedDate = null;
		else
			this.borrowedDate = df.parse(tokens[6]);
		this.category = tokens[7];
		this.imageLocation = tokens[8];
		this.isANewItem = Integer.parseInt(tokens[9]);
		//tokens[10] is set in the derived class Book/Video/etc. (Author/Director)
	}

	private String itemId;
	private String title;
	private String location;
	private String status;
	private double price;
	private Date dueDate;
	private Date borrowedDate;
	private String category;
	private int isANewItem;
	private String imageLocation;

	public void updateItemStatus()
	{
		status = "Status";
	}
	public boolean containsString(String searchQuery) 
	{
		if(title.toLowerCase().contains(searchQuery.toLowerCase()))
			return true;
		return false;
	}

	public double returnItem() 
	{
		double fine = 0.0;
		
		Date today = new Date();
		if(this.dueDate.before(today))
		{
			int overdueNoOfDays = (int) ((today.getTime() - this.dueDate.getTime())/(1000*60*60*24));
			fine = overdueNoOfDays * Item.ITEM_FINE_PER_DAY.get(this.getType());
			
			String message = "The item <" + this.itemId + "> you are returning is PAST DUE with a fine of $" + fine;
			String title = "ITEM-OVERDUE FINE NOTICE";
			JOptionPane.showMessageDialog(null, message, title, JOptionPane.OK_OPTION);
		}
		
		if(this.status.equalsIgnoreCase("RESERVED"))
		{
			setChanged();
			this.notifyObservers();
		}
		else
			this.status = "AVAILABLE";
		
		this.dueDate = null;
		this.borrowedDate = null;
		
		return fine;
	}
	public double getPrice() 
	{
		return this.price;
	}
	public void lost() 
	{
		this.status = "NOT AVAILABLE";
		this.dueDate = null;
		this.borrowedDate = null;
		this.location = "";
	}
	public boolean isAvailableForCheckout()
	{
		if(this.status.equalsIgnoreCase("AVAILABLE"))
			return true;
		
		return false;
	}
	public void checkout()
	{
		this.borrowedDate = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(this.borrowedDate); 
		c.add(Calendar.DATE, Item.ITEM_BORROW_DURATIONS.get(this.getType())); 
		this.dueDate = new Date(c.getTimeInMillis());
		this.status = "BORROWED";
	}
	public boolean isAvailableForReserve()
	{
		if(this.status.equalsIgnoreCase("BORROWED"))
			return true;
		
		return false;
	}
	public void reserve()
	{
		this.status = "RESERVED";
	}
	public String getId()
	{
		return this.itemId;
	}	
	public String getType()
	{
		if(this.itemId.startsWith("N"))
			return this.itemId.substring(0, 2);
		else
			return this.itemId.substring(0, 1);
	}
	public String getTitle() 
	{
		return this.title;
	}
	public void print()
	{
		System.out.println(itemId + "\t" + title + "\t" + status + "\n");
	}
	public boolean isOverdue()
	{
		if(this.dueDate == null)
			return false;
		
		Date todaysDate = new Date();
		if (todaysDate.after(dueDate))
			return true;
		return false;		
	}
	public String getCategory() 
	{
		return this.category;
	}
	public String toString()
	{
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm"); 

		if(this.status.equalsIgnoreCase("BORROWED"))
			return "\t" + this.title + "\t" + df.format(this.dueDate) + "\t" + df.format(this.borrowedDate);
		else
			return "\t" + this.title + "\t" + this.status;
	}
	public String getItemDetails()
	{
		return "\t" + this.title + "\t" + this.category + "\t" + this.getType() + "\t" + this.location;
	}
	
	public String serializeItem() 
	{
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
		String serializedItem = "";
		serializedItem = this.itemId + ";"
				+ this.title + ";"
				+ this.location + ";"
				+ this.status + ";"
				+ this.price + ";";
		
		if(this.dueDate == null)
			serializedItem += "" + ";";
		else
			serializedItem += df.format(this.dueDate) + ";";
		
		if(this.borrowedDate == null)
			serializedItem += "" + ";";
		else
			serializedItem += df.format(this.borrowedDate) + ";";
		
		serializedItem += this.category + ";"
				+ this.imageLocation + ";"
				+ this.isANewItem;
		
		return serializedItem;
	}

}


